/*
 * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.pig4cloud.pig.common.log.util;

import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import com.pig4cloud.pig.admin.api.entity.SysLog;
import com.pig4cloud.pig.common.log.filter.FieldToEmptyStringFilter;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.StringUtils;
import org.jpedal.parser.shape.S;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;


/**
 * 系统日志工具类
 *
 * @author L.cm
 */
@UtilityClass
public class SysLogUtils {
	private static Logger logger= LoggerFactory.getLogger(SysLogUtils.class);

	public SysLog getSysLog(Object[] arr) {
		HttpServletRequest request = ((ServletRequestAttributes) Objects
				.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
		SysLog sysLog = new SysLog();
		//未登录时 username为空
		String userName = getUsername();
		if (StringUtils.isNotBlank(userName)) {
			sysLog.setCreateBy(Objects.requireNonNull(userName));
		}
		sysLog.setType(LogTypeEnum.NORMAL.getType());
		sysLog.setRemoteAddr(ServletUtil.getClientIP(request));
		sysLog.setRequestUri(URLUtil.getPath(request.getRequestURI()));
		sysLog.setMethod(request.getMethod());
		sysLog.setUserAgent(request.getHeader("user-agent"));
		try{
			sysLog.setParams(getRequestJsonString(request,arr));
		}catch (Exception e){
			logger.error("getSysLog is error",e);
		}
		sysLog.setServiceId(getClientId());
		return sysLog;
	}

	/**
	 * 获取客户端
	 * @return clientId
	 */
	private String getClientId() {
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		if (authentication instanceof OAuth2Authentication) {
			OAuth2Authentication auth2Authentication = (OAuth2Authentication) authentication;
			return auth2Authentication.getOAuth2Request().getClientId();
		}
		return null;
	}

	/**
	 * 获取用户名称
	 * @return username
	 */
	private String getUsername() {
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		if (authentication == null) {
			return null;
		}
		return authentication.getName();
	}

	/***
	 * 获取 request 中 json 字符串的内容
	 *
	 * @param request
	 * @return : <code>byte[]</code>
	 * @throws IOException
	 */
	public static String getRequestJsonString(HttpServletRequest request,Object[] arr)
			throws IOException {
		String submitMehtod = request.getMethod();
		// GET
		if (submitMehtod.equals("GET")) {
			if(StringUtils.isNotBlank(request.getQueryString())){
				return new String(request.getQueryString().getBytes("iso-8859-1"),"utf-8").replaceAll("%22", "\"");
			}else{

				return argsArrayToString(arr);
			}

			// POST
		} else {
			//请求参数
			return argsArrayToString(arr);
		}
	}



	/**
	 * 请求参数拼装
	 *
	 * @param paramsArray
	 * @return
	 */
	private static String argsArrayToString(Object[] paramsArray) {
		String params = "";
		if (paramsArray != null && paramsArray.length > 0) {
			for (int i = 0; i < paramsArray.length; i++) {
//				Object jsonObj = JSON.toJSON(paramsArray[i]);
//				String jsonObj = toJson(paramsArray[i],"file","files");
				String jsonObj = JSON.toJSONString(paramsArray[i], new FieldToEmptyStringFilter());
				params += jsonObj + " ";
			}
		}
		if(StringUtils.isNotBlank(params)){
			return params.replaceAll("\\\\","").trim();
		}
		return params;
	}

	private static String toJson(Object o, String... excludeKeys) {
		List<String> excludes = Arrays.asList(excludeKeys);
		SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
		filter.getExcludes().addAll(excludes);
		return JSON.toJSONString(o, filter);
	}


}
